package com.webserver.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

public class HttpRequest {
    //请求行相关信息
    private String method;//请求方式
    private String uri;//抽象路径
    private String protocol;//协议版本
    private String requestURI;//保存uri中请求部分
    private String queryString;//保存uri中参数部分
    private byte[] bytes;
    private Map<String,String> querymap = new HashMap<>();
    private Map<String,String> headers = new HashMap<>();
    private Socket socket;
    //实例化HttpRequest的过程就是解析的过程，通过给定的Socket读取客户端发送的请求
    public HttpRequest(Socket socket) throws EmptyRequestException {
        this.socket=socket;
        try {
            parseRequestLine();
            parseHeaders();
            parseContent();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private String readLine() throws IOException {
        StringBuilder builder = new StringBuilder();
        InputStream in = socket.getInputStream();
        int d;
        char pre='a',cur;//pre表示上次读取到的字符,cur表示本次读取到的字符
        while((d = in.read()) != -1){
            cur = (char)d;//将读取的每个字节强转为一个字符(英文,数字,符号都是单字节编码)
            if(pre==13&&cur==10){
                break;
            }
            builder.append(cur);
            pre = cur;
        }
        return builder.toString().trim();
    }
    private void parseRequestLine() throws IOException, EmptyRequestException {
        //读取客户端发送过来的一行字符串内容(以CRLF结尾)，并按照空格拆分
        String line = readLine();
        if(readLine().isEmpty())
            throw new EmptyRequestException();
        String[] data = line.split("\\s");
        method = data[0];
        uri = data[1];
        protocol = data[2];
        parseUri();
        System.out.println("line:"+line);
    }
    //解析消息头
    private void parseHeaders() throws IOException {
        //读取客户端发送过来的一行字符串内容(以CRLF结尾)
        while (true) {
            String line = readLine();
            if (line.isEmpty()) {
                break;
            }
            System.out.println(line);
            //拆分消息头后存入Map
            String[] arr = line.split(":\\s");
            headers.put(arr[0],arr[1]);
        }
        System.out.println("headers:"+headers);
    }
    private void parseContent(){
        //正文存在与否判定
        if("post".equalsIgnoreCase(method)){
            System.out.println("进来了");
            //获取正文长度的字符串并转为int
            int len = Integer.parseInt(headers.get("Content-Length"));
            //创建数组，赋予正文长度的容量
            bytes=new byte[len];
            //读取正文字节并存入数组
            try {
                InputStream inputStream = socket.getInputStream();
                inputStream.read(bytes);
                if ("application/x-www-form-urlencoded".equals(headers.get("Content-Type"))) {
                    String line = new String(bytes, "iso8859-1");
                    line=URLDecoder.decode(line,"utf-8");
                    cut(line);
                    System.out.println("正文内容"+line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("出去了");
    }
    public String getMethod() {
        return method;
    }
    public String getUri() {
        return uri;
    }
    //进一步解析URI
    private void parseUri(){
        //解析16进制的文字转为utf-8编码
        try {
            uri= URLDecoder.decode(uri,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (uri.contains("?")){
            String[] u=uri.split("\\?");
            requestURI=u[0];
            if(u.length>1) {
                queryString = u[1];
                cut(queryString);
            }
        }else {
            requestURI=uri;
        }
        System.out.println("requestURI:"+requestURI);
        System.out.println("queryString:"+queryString);
        System.out.println("querymap:"+querymap);
    }
    private void cut(String string){
        String[] strings = string.split("\\&");
        for (int i = 0; i < strings.length; i++) {
            String[] s = strings[i].split("\\=");
            if(s.length>1) {
                querymap.put(s[0], s[1]);
            }else {
                querymap.put(s[0], null);
            }
        }
    }
    public String getRequestURI() {
        return requestURI;
    }
    public String getQueryMap(String name) {
        return querymap.get(name);
    }
}
